#include "Dri_Timer_0.h"

/**
 * @brief 创建一个数组,用于存入指针函数
 * 
 */
static TIMER0_CALLBACK S_Timer0_CallBack_Array[MAX_CALLBACK_ARRAR];

/**
 * 初始化定时器中断
 */
void Dri_Timer0_Init(void)
{
    // 开启中断
    // 开启总总断
    EA = 1;
    // 开启第一个定时器
    ET0 = 1;

    // 选择是定时模式/计算模式,工作模式
    // 用来 TMOD 寄存器,但是这个不能寻址, 第0个定时器是TMOD的低四位
    // ct = 0(使用定时器),使用16位定时器, m1 = 0, m0 = 1
    TMOD &= 0XF0;
    TMOD |= 0X01;

    // 设置时间,1毫秒
    // 因为晶振= 11059200 秒/hz, 我们选择是12T为一个机器时钟,设置1毫秒多少个机器时钟  --> 11059200 / 12X1000  ≈ 922
    // 因为是8位溢出以后,进行定时器触发所以 16bit 11111111 11111111 -> 10进制 65535,
    //  但是65536 才能溢出进行定时器触发 所以 但是(65536 - 922) = 64614 才是初始值,等到了但是65536就触发
    // 64614 = 0XFC66 ,TL0 是低8位所以会只有66,
    TL0 = 64614;
    // TH0 是高8位,所以把FC 给他
    TH0 = 64614 >> 8;

    // 定时器开始计算
    TR0 = 1;
}

/**
 * @brief 添加回调函数
 *
 * @param callBack 回调函数
 * @return bit 添加成功 = 1, 失败 = 0
 */
bit Dri_Timer_AddCallBack(TIMER0_CALLBACK callBack)
{
    u8 i;
    for ( i = 0; i < MAX_CALLBACK_ARRAR; i++)
    {
        // 存在则返回1
        //TIMER0_CALLBACK one = S_Timer0_CallBack_Array[i];
        if (S_Timer0_CallBack_Array[i] == callBack)
        {
            return 1;
        }
    }

    // 不存在,则添加
    for (i = 0; i < MAX_CALLBACK_ARRAR; i++)
    {
       // 存在则返回1
       // TIMER0_CALLBACK one = S_Timer0_CallBack_Array[i];
        if (S_Timer0_CallBack_Array[i] == NULL)
        {
            S_Timer0_CallBack_Array[i] = callBack;
            return 1;
        }    
    }
    return 0;
}

/**
 * @brief 删除回调函数
 *
 * @param callBack 回调函数
 * @return bit 删除成功 = 1, 删除失败 = 0
 */
bit Dri_Timer_DelCallBack(TIMER0_CALLBACK callBack)
{
    u8 i;
    // 判断是否存在
    for ( i = 0; i < MAX_CALLBACK_ARRAR; i++)
    {
        // 存在则返回1
        TIMER0_CALLBACK one = S_Timer0_CallBack_Array[i];
        if (one == callBack)
        {
            S_Timer0_CallBack_Array[i] = NULL;
            return 1;
        }
    }
    return 0;
}

/**
 * @brief 删除全部
 * 
 * @param callBack 
 * @return bit 
 */
void Dri_Timer_DellAll(){
      u8 i;
    // 判断是否存在
    for ( i = 1; i < MAX_CALLBACK_ARRAR; i++)
    {
       S_Timer0_CallBack_Array[i] = NULL;
    }
}

/**
 * @brief 定时器中断服务程序
 *
 */
void Dri_Timer0_interrupt() interrupt 1
{
    u8 i;
    for (i = 0; i < MAX_CALLBACK_ARRAR; i++)
    {
       TIMER0_CALLBACK one =   S_Timer0_CallBack_Array[i];
        if (one != NULL)
        {
            one();
        }
    }

    // 重新设置计算
    // 64614 = 0XFC66 ,TL0 是低8位所以会只有66,
    TL0 = 64614;
    // TH0 是高8位,所以把FC 给他
    TH0 = 64614 >> 8;
}